#include "task.h"
#include "mm.h"
#include "assert.h"
#include "string.h"
#include "kernel.h"

task_t *task_table[NR_TASKS] = {0};

extern task_t *current;

static int find_empty_process()
{
    int i = 0;
    for (i = 0; i < NR_TASKS; i++)
    {
        if (0 == task_table[i])
        {
            return i;
        }
    }
    printk("no empty process\n");
    return -1;
}

task_t * task_create(task_fun_t fun, char* name)
{
    task_t* task = kmalloc(4096);
    task->state = TASK_INIT;
    task->pid = find_empty_process();
    assert(task->pid!= -1);

    task_table[task->pid] = task;
    task->function = fun;
    strcpy(task->name, name);
    task->esp0 = (i64) task + PAGE_SIZE;
    task->state = TASK_READY;
    return task;
}

task_fun_t get_task_function(task_t *task)
{
    return task->function;
}

task_context_t *get_task_context(task_t *task)
{
    return &task->context;
}

void task_exit(task_t *task)
{
    for (size_t i = 0; i < NR_TASKS; i++)
    {
        task_t* t = task_table[i];
        if (t == task)
        {
            printk("task %s exit\n", task->name);
            task_table[i] = NULL;
            current = NULL;
            kfree_s(task, 4096);
            break;
        }
    }
    
}

int inc_scheduling_times(task_t *task)
{
    return task->scheduling_times++;
}